package com.superb.common.utils;

import com.superb.common.core.enums.SuperbCode;
import com.superb.common.core.exception.SuperbException;
import lombok.extern.slf4j.Slf4j;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Base64;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author sking
 * @version 1.0.0.0
 * @Title 脱敏工具类
 * @date 2021/12/22 17:08
 */
@Slf4j
public class AesUtils {

    /**
     * 加密算法
     */
    private static final String KEY_ALGORITHM = "AES";
    /**
     * 算法/模式/补码方式
     */
    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
    private static final int KEY_LENGTH_16 = 16;
    private static final int KEY_LENGTH_24 = 24;
    private static final int KEY_LENGTH_32 = 32;
    /**
     * 编码格式
     */
    private static final String CODE = "utf-8";
    /**
     * base64验证规则
     */
    private static final String BASE64_RULE = "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)=?$";

    /**
     * 正则验证对象
     */
    private static final Pattern PATTERN = Pattern.compile(BASE64_RULE);

    /**
     * 加密
     * @param content 加密内容
     * @param key 加密秘钥
     * @return
     */
    public static String encrypt(String content, String key) {
        if (isBase64(content)) {
            return content;
        }
        try {
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key));
            byte[] bytes = cipher.doFinal(content.getBytes());
            return Base64.getEncoder().encodeToString(bytes);
        } catch (Exception e) {
            throw new SuperbException(SuperbCode.AES_ENCRYPT, e);
        }
    }

    /**
     * 数据解密
     * @param content 解密内容
     * @param key 秘钥
     * @return
     */
    public static String decrypt(String content, String key) {
        if (!isBase64(content)) {
            return content;
        }
        try {
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key));
            byte[] bytes = cipher.doFinal(Base64.getDecoder().decode(content.getBytes()));
            return new String(bytes);
        } catch (Exception e) {
            throw new SuperbException(SuperbCode.AES_DECRYPT, e);
        }
    }

    private static SecretKeySpec getSecretKey(String key) throws UnsupportedEncodingException {
        byte[] bytes = key.getBytes(CODE);
        int length = bytes.length;
        int newLength;
        if (length <= KEY_LENGTH_16) {
            newLength = KEY_LENGTH_16;
        } else if (length <= KEY_LENGTH_24) {
            newLength = KEY_LENGTH_24;
        } else {
            newLength = KEY_LENGTH_32;
        }
        return new SecretKeySpec(Arrays.copyOf(key.getBytes(), newLength), KEY_ALGORITHM);
    }

    /**
     * 判断是否为 base64加密
     *
     * @param str 参数
     * @return 结果
     */
    public static boolean isBase64(String str) {
        Matcher matcher = PATTERN.matcher(str);
        return matcher.matches();
    }

}
